package main

import (
	"fmt"
	"os"
	"path/filepath"
	"peilian-api/app/global/databases/tables"
	"peilian-api/utils/encrypt"
	"strings"
	"time"

	"github.com/tealeg/xlsx"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 学历是固定的，无需加入数据库
var EducationArr = []string{"大专", "本科", "硕士", "博士"}

// 年级固定
var GradeArr = []string{"2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023"}

var AgentId = 74
var PwdPrefix = "YS"

var SchoolConstituteId int
var InserSchool string

var db *gorm.DB
var err error

const (
	userName = "youshi"
	pwd      = "1G?ywxyrlis4Orl"
	ipCode   = "10.9.93.161:3306"
	dbName   = "peilian"
)

func generatePwd(sno string) string {
	// 1. 根据学校名称获取学校前缀
	// 2. 生成密码
	// rsaPwd, _ := encrypt.RsaEncode(prefix + sno)
	userPwd, _ := encrypt.EncryptPassword(PwdPrefix + sno)
	return userPwd
}

func CreateDB() error {
	dbinfo := strings.Join([]string{userName, ":", pwd, "@tcp(", ipCode, ")/", dbName, "?charset=utf8&parseTime=True&loc=Local"}, "")
	db, err = gorm.Open(mysql.Open(dbinfo), &gorm.Config{
		DisableForeignKeyConstraintWhenMigrating: true,
	})
	if err != nil {
		return err
	}
	return nil
}

func ReadExcle(filepath string) [][][]string {
	out, err := xlsx.FileToSlice(filepath)
	if err != nil {
		panic(err.Error())
	}
	return out
}
func Contains(elements []string, needle string) bool {
	for _, v := range elements {
		if needle == v {
			return true
		}
	}

	return false
}

type Model struct {
	Id        uint           `gorm:"primarykey" json:"id"`
	CreatedAt time.Time      `json:"created_at" format:"2006-01-02 15:04:05"`
	UpdatedAt time.Time      `json:"updated_at"`
	DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

type Constitute struct {
	Model
	Type       string `json:"type"`
	Name       string `json:"name"`
	BelongToId int    `json:"belong_to_id"`
	AgentId    int    `json:"agent_id"`
}

type Users struct {
	CreatedAt    time.Time `json:"created_at" format:"2006-01-02 15:04:05"`
	UpdatedAt    time.Time `json:"updated_at"`
	Id           int       `json:"id"`
	Name         string    `json:"name"`
	Sno          string    `json:"sno"`
	Password     string    `json:"password"`
	AccountName  *string   `json:"account_name"`
	Type         string    `json:"type"`
	School       string    `json:"school"`
	Academy      string    `json:"academy"`
	Profession   string    `json:"profession"`
	Grade        string    `json:"grade"`
	Education    string    `json:"education"`
	ConstituteID uint      `json:"constitute_id"`
	RoleId       uint      `json:"role_id"`
	AgentID      uint      `json:"agent_id"`
	Phone        string    `json:"phone"`
	Email        string    `json:"mail"`
	Level        int       `json:"level"`
}

type CommonConf struct {
	Model
	ConfKey    string `json:"conf_key" gorm:"type:varchar(20);comment:指定key"`
	Type       uint   `json:"type" gorm:"type:tinyint(3);default:0;comment:类型"`
	ConfValue  string `json:"conf_value" gorm:"type:longtext;comment:详细信息"`
	Remarks    string `json:"remarks" gorm:"type:varchar(256);default:\"\";comment:详细备注"`
	ExtendInfo string `json:"extend_info" gorm:"type:varchar(1024);default:\"\";comment:扩展信息"`
	Other      string `json:"other" gorm:"type:varchar(256);default:\"\";comment:其他信息"`
}

var academyMap = make(map[string]uint)
var professionMap = make(map[string]uint)

// 创建学院专业
func CreateConstitute(academy, profession string) uint {
	academyId, ok := academyMap[academy]
	// 创建院系
	if !ok || academyId == 0 {
		var a Constitute
		db.Table("constitute").Where("type = ? and belong_to_id = ? and name = ?", "academy", SchoolConstituteId, academy).Select("id,name,type,belong_to_id").Find(&a)
		if a.Id == 0 {
			a = Constitute{Name: academy, Type: "academy", BelongToId: SchoolConstituteId}
			err = db.Table("constitute").Create(&a).Error
			if err != nil {
				panic(err)
			}
		}
		academyMap[academy] = a.Id
		academyId = a.Id
	}
	key := fmt.Sprintf("%s-%d", profession, academyId)
	pId, ok := professionMap[key]
	// 创建专业
	if !ok || pId == 0 {
		var p Constitute
		db.Table("constitute").Where("type = ? and belong_to_id = ? and name = ?", "profession", academyId, profession).Select("id,name,type,belong_to_id").Find(&p)
		if p.Id == 0 {
			p = Constitute{Name: profession, Type: "profession", BelongToId: int(academyId)}
			err = db.Table("constitute").Create(&p).Error
			if err != nil {
				panic(err)
			}
		}
		pId = p.Id
		professionMap[key] = pId
	}
	//fmt.Println(academyId, pId)
	return pId
}

// 导入学生
func insertStudent(out [][][]string) {
	var users []Users
	for s := 0; s < len(out); s++ {
		for i := 1; i < len(out[s]); i++ {
			if len(out[s][i]) < 6 {
				fmt.Println(s, i, out[s][i])
				continue
			}
			name := out[s][i][0]
			sno := out[s][i][1]
			academy := out[s][i][2]
			profession := out[s][i][3]
			education := out[s][i][4]
			grade := out[s][i][5]
			phone := out[s][i][6] // 最后一列增加手机号
			//constitute_id := q[academy][profession]
			if len(sno) > 12 {
				sno = sno[-(12 - len(sno)):]
			}
			// 创建学院和专业
			constitute_id := CreateConstitute(academy, profession)

			var user Users
			user.CreatedAt = time.Now().UTC()
			user.UpdatedAt = time.Now().UTC()
			user.Name = name
			user.Type = "normal"
			user.School = InserSchool
			user.Academy = academy
			user.Profession = profession
			user.Grade = grade
			user.AgentID = uint(AgentId)
			user.RoleId = 0
			user.Sno = sno
			user.Level = 0
			user.ConstituteID = constitute_id
			user.Education = education
			user.Password = generatePwd(sno)
			if phone != "" {
				user.Phone = phone
			}

			// db.Table("users").Save(&user)
			users = append(users, user)
			if len(users) == 50 {
				db.Table("users").Model(&user).CreateInBatches(users, len(users))
				users = []Users{}
				fmt.Println(s, i)
			}
			// db.Table("users").Where("sno = ? and school = ?", sno, InserSchool).FirstOrCreate(&user)
			// fmt.Println(user)
			// break
		}
	}
	if len(users) > 0 {
		db.Table("users").CreateInBatches(users, len(users))
	}
}

func main() {
	CreateDB()
	dir, _ := os.Getwd()
	filePath := dir + "/scripts/school/beihang/广州市轻工技师学院.xlsx"
	InserSchool = strings.Split(filepath.Base(filePath), ".")[0]
	InserSchool = strings.Split(InserSchool, "_")[0]
	// 获取id
	//var school tables.School
	//db.Table("school").Where("name = ?", InserSchool).Select("id,name").Find(&school)
	//if school.ID != 0 {
	//	SchoolConstituteId = int(school.ID)
	//}
	// 创建密码后缀的记录

	if PwdPrefix != "" {
		var conf CommonConf
		db.Table("common_conf").Where("conf_key = ? and remarks = ?", "school", InserSchool).Select("id").Find(&conf)
		if conf.Id == 0 {
			conf = CommonConf{
				ConfKey:    "school",
				Type:       1,
				ConfValue:  PwdPrefix,
				Remarks:    InserSchool,
				ExtendInfo: "密码前缀",
			}
			err = db.Table("common_conf").Create(&conf).Error
			if err != nil {
				panic(err)
			}
		}
	}

	var constitute tables.Constitute
	db.Table("constitute").Where("name = ?", InserSchool).Select("id,name").Find(&constitute)
	if constitute.ID != 0 {
		SchoolConstituteId = int(constitute.ID)
	}

	s := ReadExcle(filePath)
	//fmt.Println(s)
	//dealMap()
	// analysis(s)
	// dealMap()
	insertStudent(s)
}
